package databasex

import (
	"common/zapx"
	"errors"
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
	"models/dal/query"
	"strings"
	"time"
)

type Manage struct {
	*gorm.DB
	Mysql struct {
		Dns   string
		Debug bool
	}
}

type ManageOpt func(m *Manage)

var M *Manage

// WithMysqlDns 设置mysql的连接地址
func WithMysqlDns(dns string) ManageOpt {
	return func(m *Manage) {
		m.Mysql.Dns = dns
	}
}

// WithDebug debug模式配置
func WithDebug(debug bool) ManageOpt {
	return func(m *Manage) {
		m.Mysql.Debug = debug
	}
}

// Init 初始化
func Init(opts ...ManageOpt) error {
	M = &Manage{
		Mysql: struct {
			Dns   string
			Debug bool
		}{Dns: "", Debug: false},
	}
	for _, opt := range opts {
		opt(M)
	}
	if err := M.ConnectMysql(); err != nil {
		return err
	}
	return nil
}

// ConnectMysql 连接数据库
func (m *Manage) ConnectMysql() error {
	if strings.EqualFold("", m.Mysql.Dns) {
		return errors.New("请先设置数据库连接")
	}
	db, err := gorm.Open(mysql.Open(m.Mysql.Dns), &gorm.Config{})
	if err != nil {
		return err
	}
	if m.Mysql.Debug {
		db = db.Debug()
	}
	m.DB = db
	//设置 dao的默认数据库链接
	query.SetDefault(db)
	m.PingMysql()
	return nil
}

// PingMysql 保持连接活跃
func (m *Manage) PingMysql() {
	go func() {
		for {
			<-time.After(time.Minute * 2)
			m.DB.Select("select 1;")
			zapx.Logger.Info("ping mysql server...")
		}
	}()
}
